/*
 *  Domain.cpp
 *  T3nsors
 *
 *  Created by Michael Barriault on 09-10-07.
 *  Copyright 2010 University of Guelph. All rights reserved.
 *
 */

#include "Domain.h"
#include "Macros.h"
#include "Others.h"
#include <cstdlib>
#include <cstdarg>

Domain::Domain(void) {
	return;
}

Domain::Domain(int l, ...) {
	va_list vl;
	va_start(vl, l);
	int count = l;
	O.assign(count,0);
	r.assign(2*count,0.);
	D.assign(count,0.);
	P.assign(count,0);
	FOR(i,count) P[i] = 0;
	N = count;
	O[0] = va_arg(vl,int)+1;
	FOR(i,count) {
		r[2*i] = va_arg(vl,double);
		r[2*i+1] = va_arg(vl,double);
	}
	FOR(i,count-1)
		O[i+1] = (O[0]-1) * (r[2*i+3]-r[2*i+2])/(r[1]-r[0]) + 1;
	FOR(i,count)
		D[i] = (max(i)-min(i))/(O[i]-1);
	va_end(vl);
	return;
}

Domain::~Domain(void) {
	O.clear();
	r.clear();
	D.clear();
	P.clear();
}

int Domain::operator[](int i) {
	if ( i == -1 )
		return 1;
	return O[i];
}

int Domain::operator()(void) {
	int T = 1;
	FOR(i,N)
		T *= O[i];
	return T;
}

int Domain::operator()(int A) {
	if ( A == -1 )
		return 1;
	int T = 1;
	FOR(i,A+1)
		T *= O[i];
	return T;
}

double Domain::min(int i) {
	return r[2*i];
}

double Domain::max(int i) {
	return  r[2*i+1];
}

double Domain::d(void) {
	return D[0];
}

double Domain::d(int i) {
	return D[i];
}

short& Domain::p(int i) {
	return P[i];
}

void CheckDims(Domain O1, Domain O2) {
	if ( O1.N != O2.N )
		exit(10);
	if ( O1() != O2() )
		exit(11);
	FOR(n,O1.N)
		if ( O1[n] != O2[n] )
			exit(12);
}

void CheckDims(int N1, int N2) {
	if ( N1 != N2 )
		exit(20);
}

